home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / sonido / studio.000 / studio / Ss / maxmin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-11  |  8.3 KB  |  274 lines

  1. /* MaxMin                                    */
  2. /* A program to return the maxima and minima of blocks in 8 & 16 bit samples     */
  3. /* Designed for use with TCL                            */
  4. /* Part of the 3rd Year Project by Paul D.Sharpe                */
  5. /* University of Leeds, Dept. of Electronic & Electrical Engineering         */
  6. /*                                        */
  7. /* Programmed by Paul D. Sharpe                            */
  8. /* Revision : 3                                    */
  9. /* Date : 14/2/95                                */
  10.  
  11. #include <fcntl.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14.  
  15. /* Forward Declarations */
  16. int maxmin (long blocksize, int filetype, char *filename);
  17.  
  18. /********************************************************************************/
  19. /* Three arguments are required from the Command line. The first is the size of    */
  20. /* the blocks to be scanned in samples (regardless of wordsize);         */
  21. /* The second argument is an integer in the range 0<=arg2<=3; to mean:        */
  22. /* 0 = 8 bit mono; 1 = 8 bit stereo; 2 = 16 bit mono; 3 = 16 bit stereo;    */
  23. /* The third is the filename of the file to be scanned.                */
  24. /* All errors return -1, with a message to stderr.                */
  25. int main(int argc, char *argv[])
  26. {
  27.     /*Variable Declarations */
  28.     int blcsz,fltyp;
  29.     char **endptr, filename[100];
  30.     /* Check that sufficient arguments have been given */
  31.     if (argc>2) {
  32.             /* Convert the argument strings to numbers */
  33.             /*Note:Errors are detected in the maxmin function */
  34.             blcsz=strtol (argv[1],endptr,10);
  35.             fltyp=(int)strtol(argv[2],endptr,10);
  36.             strcpy(filename,argv[3]);
  37.  
  38.             /* Call the function that does all the work */ 
  39.             maxmin (blcsz,fltyp,filename);
  40.     }
  41.     else {
  42.      fprintf(stderr,"MaxMin Error:invalid number of arguments: need blocksize and map\n");
  43.       return (-1);
  44.     }
  45.     return(0);
  46. }
  47. /********************************************************************************/
  48. /* int maxmin (long blocksize, int filetype, char *filename)                    */
  49. /* This function scans a file and works out the                 */
  50. /* maximum and minimum values of the samples within in blocks of         */
  51. /* size 'blocksize'.                                 */
  52. /* The file type is an integer indicating the number of channels and        */
  53. /* wordsize of the sample;                               */
  54. /* 0 = 8 bit mono                                */
  55. /* 1 = 8 bit stereo                                */
  56. /* 2 = 16 bit mono                                */
  57. /* 3 = 16 bit stereo                                */
  58. /* ie first bit mono/stereo, second bit 8/16bit                 */
  59. /* Note that the blocksize must be even, especially if stereo.            */
  60. /* It also counts the number of samples in the file.                */
  61. /* The results are send to the stdout as a TCL list with two elements;        */
  62. /*     1 : a list of the minima and maxima; { min1 max1 }...{minN maxN}    */
  63. /*     2 : the number of samples in the file { total }                */
  64. /* These can be easily accesed in tcl using lindex.                */
  65. /* The filename is simply the name of the file to be scanned            */
  66.  
  67. int maxmin (long blocksize, int filetype, char *filename)
  68. {
  69.     
  70.    /*Variable Declarations                             */
  71.       /* file descriptor */
  72.     int fd;                    
  73.     /* buffers to contain the blocks to be scanned */
  74.     unsigned char *buffer8;    
  75.     short *buffer16;
  76.     /* pointer to assist in read operation */
  77.     char *readptr;
  78.     /* variables to contain the maximum and minimum values */
  79.         unsigned char min8,max8;
  80.     short min16, max16,test;
  81.     float normax,normin;    /* (for the normalised results) */
  82.     /* variable to add up the samples */
  83.     long total=0;
  84.     /* flags and counting variables */
  85.     int i,got,stereo;
  86.     int next_count,bytes;
  87.  
  88.     /* Open the file                                */
  89.  
  90.     if ((fd=open(filename,(O_RDONLY),0))==-1) 
  91.         {
  92.             fprintf(stderr,"maxmin Error:file open failed");
  93.             exit(-1);
  94.         }
  95.  
  96.    /* Check for stereo bit and convert blocksize into bytes accordingly.    */
  97.    if (1&filetype) { 
  98.             stereo=1; 
  99.             bytes=blocksize*2; 
  100.               }
  101.    else        { 
  102.             stereo=0;
  103.             bytes=blocksize;
  104.            }
  105.    /* Print the initial bracket to surround the list                */
  106.    printf("{");
  107.  
  108.    /* Check that the blocksize is not zero                    */    
  109.    if (blocksize>0)
  110.       {
  111.     /* Scan the file in blocks.                        */
  112.     /* Because the data type for 8 bit and 16 bit samples is different these*/
  113.     /* are kept separate.                             */
  114.     /* 8 bit data is of type unsigned char.                    */
  115.     /* 16 bit data is of type signed short.                    */
  116.     
  117.     /* The 8 bit case.                            */
  118.     /* The second bit of filetype indicates whether 8 or 16 bit, hence the    */
  119.     /* bitwise operation in the condition.                    */
  120.     if (!(filetype>>1))
  121.     {
  122.         /* Allocate memory for the buffer.                  */
  123.           buffer8=(unsigned char*) calloc (bytes,sizeof(unsigned char));
  124.         /* Check that memory was allocated correctly */
  125.         if (buffer8==NULL) 
  126.             { 
  127.             fprintf (stderr,"maxmin: Malloc Error");
  128.             exit(-1);  
  129.             }
  130.  
  131.         /* Loop to scan the file; continue until end of file        */
  132.         while ((bytes > 0) && (got=read(fd,buffer8,bytes))>0 )
  133.         {
  134.             /* Check for errors during read                */
  135.             if (got== -1)  
  136.                 { 
  137.                    fprintf (stderr,"maxmin: Error in reading file.");    
  138.                    exit(-1);
  139.                 }
  140.  
  141.             /*Set minima and maxima testers to the central position;*/
  142.             /* recall that the data is unsigned char, hence the 128.*/
  143.             min8=128; max8=128;
  144.             
  145.             /* Loop to scan the block.                */
  146.             for (i=0; i<got; i++)
  147.             {
  148.                /*Average stereo channels -                */
  149.                /*(last sample is not averaged,if blocksize not even)*/
  150.                if ((stereo)&&((i+1)!=got)) 
  151.                  {
  152.                 /* Average */
  153.                 buffer8[i]=(buffer8[i]+buffer8[i+1] )/2;
  154.                 /* Increment i to account for the stereo word    */
  155.                 i++;
  156.                  }
  157.             /*Compare the current value with the previous max & min    */
  158.             if (buffer8[i]>max8) { max8=buffer8[i]; }
  159.             if (buffer8[i]<min8) { min8=buffer8[i]; }
  160.  
  161.             /* Count the total number of samples            */
  162.             total++;
  163.         }
  164.  
  165.         /* The max & min values are inverted and normalised here.    */
  166.         /* This is for the purpose of plotting on the tk canvas,     */
  167.         /* The coordinate system requires that the maximum is smaller    */
  168.         /* than the minimum.                        */
  169.         /* It is normalised for flexibility.                */
  170.         normax=(float)(255-max8)/255;
  171.         normin=(float)(255-min8)/255;
  172.  
  173.         /* Print the normalised, inverted maxima and minima to stdout     */
  174.         printf("{ %1.6f %1.6f } ",normin,normax);
  175.         
  176.         /* Check whether the amount of bytes requested were obtained.    */
  177.         /* If not end of file has been reached                */      
  178.         if (got < bytes)
  179.             bytes = 0;
  180.             }
  181.         
  182.         /* free allocated memory                     */
  183.         free (buffer8);
  184.     }
  185.     /* 16 bit case.                                */
  186.     else
  187.     {
  188.         
  189.         /* Allocate memory for the buffer. (no.of blocks=bytes)        */
  190.         buffer16=(short*) (calloc (bytes, sizeof(short) ) );
  191.  
  192.         /* Check that memory was allocated correctly */
  193.         if (buffer16==NULL)
  194.             { 
  195.                    fprintf (stderr,"maxmin:Malloc Error");
  196.                 exit(-1);
  197.             }
  198.  
  199.         /* convert blocksize further to actual bytes            */
  200.         bytes *=2;
  201.  
  202.         /* Set a char pointer for read function                */
  203.         readptr=(char *) buffer16;
  204.  
  205.         /* Loop to scan the file; continue until end of file        */
  206.         while ((bytes > 0) && (got=read(fd,readptr,bytes))>0 )
  207.         {
  208.             /* Check for errors during read                */
  209.             if (got== -1)  
  210.                 { 
  211.                    fprintf (stderr,"maxmin: Error in reading file.");    
  212.                    exit(-1);
  213.                 }
  214.  
  215.             /*Set minima and maxima testers to the central position;*/
  216.             min16=0; max16=0;
  217.             
  218.         /* Loop to scan the block.                    */    
  219.         for (i=0; i<(got/2) ; i++)
  220.         {  
  221.             /*Average stereo channels -                */
  222.             /*(last sample is not averaged,if blocksize not even)    */
  223.             if ((stereo)&&((i+1)<(got/2))) 
  224.                 {
  225.                   /* Average                    */
  226.                   buffer16[i]=(buffer16[i]+buffer16[i+1] )/2;
  227.                   /* Increment i to account for the stereo word    */
  228.                   i++;
  229.                 }
  230.  
  231.             /*Compare the current value with the previous max & min    */
  232.             if (buffer16[i]>max16) { max16=buffer16[i]; }
  233.             if (buffer16[i]<min16) { min16=buffer16[i]; }
  234.  
  235.             /*Count the total number of samples*/
  236.             total++;
  237.         }
  238.  
  239.         /* The max & min values are inverted and normalised here.    */
  240.         /* This is for the purpose of plotting on the tk canvas,     */
  241.         /* The coordinate system requires that the maximum is smaller    */
  242.         /* than the minimum.                        */
  243.         /* It is normalised for flexibility.                */
  244.         normax= (float)(32767-max16)/65535;
  245.         normin= (float)(32767-min16)/65535;
  246.         
  247.         /* Print the normalised, inverted maxima and minima to stdout     */
  248.         printf("{ %1.6f %1.6f } ",normin,normax);
  249.         
  250.         /* Check whether the amount of bytes requested were obtained.    */
  251.         /* If not end of file has been reached                */      
  252.         if (got < bytes)
  253.             bytes = 0;
  254.             }
  255.         
  256.         /* free allocated memory                     */
  257.         free (buffer16);
  258.        }
  259.    } 
  260.    else { 
  261.        /*If it has come to this, an invalid blocksize has been given    */
  262.        fprintf  (stderr, "maxmin error: invalid blocksize, must be >0.");
  263.        exit (-1);
  264.     }
  265.  
  266.    close(fd);
  267.    /* Print the closing braces and the total samples to stdout.            */
  268.    printf ("} {{ %d }}",total);
  269.  
  270.    /* Exit normally */
  271.    exit (0);
  272. }
  273.  
  274.